//在实际开发的过程当中，经常有需要拷贝数据的情况
//  1.对于简单数据类型

// var data_1 = 1;
// // 直接使用 = 赋值运算符可以获得两份相同的数据
// var data_2 = data_1;
// data_2 = 0;
// console.log(data_1,data_2);

// 2.对于复杂数据类型
//      当要拷贝的对象为数组，对象等复杂数据类型是
//      实际上变量名获得的是数据的地址，真实数据存放于内存的堆区
//      因此在拷贝的过程中，实际上是拷贝了两份地址，并没有真正再创建一份数据

// var data_1 = [0,1,2];
// var data_2 = data_1;
// data_2[0] = 100;
// console.log(data_1,data_2);

// var data_1 = {a:1,b:2}
// var data_2 = data_1;
// data_2.a = 100;
// console.log(data_1,data_2);

// 由结果可见data_1 data_2都指向同一份数据

// 为了解决对复杂数据类型的拷贝问题，出现了浅拷贝和深拷贝方法

// 浅拷贝（遍历对象，依次赋值）
function shallowCopy(newObj, target) {
  //遍历要拷贝的对象
  for (let i in target) {
    newObj[i] = target[i];
  }
}

// 浅拷贝仅适用于只有一层结构的复杂数据，当复杂数据类型进行嵌套时，即使进行遍历又会回到复制地址的问题
// var data_1 = { a: 1, b: 2};
// var data_2 = {};
// shallowCopy(data_2, data_1);
// console.log(data_2);

// 深拷贝通过递归不断挖掘嵌套解决问题
function deepCopy(newObj, target) {
  //遍历要拷贝的对象
  for (let i in target) {
    // 加入判断条件，如果为简单数据类型则直接赋值
    let flag =
      ["string", "number", "boolean", "undefined"].includes(typeof target[i]) ||
      target[i] === null;

    if (flag) {
      newObj[i] = target[i];
    }
    // 若不是简单类型则递归深拷贝
    else if (Array.isArray(target[i])) {
      newObj[i] = [];
      deepCopy(newObj[i], target[i]);
    } else {
      newObj[i] = {};
      deepCopy(newObj[i], target[i]);
    }
  }
}
var data_1 = {
  a: 1,
  b: 2,
  c: [1, 2, 3],
  u: undefined,
  m: null,
  info: {
    name: "Lucy",
  },
};
var data_2 = {};
deepCopy(data_2, data_1);
data_2.info.name = "David";
console.log(data_1, data_2);


// jquery的extend方法
// jQuery.extend([deep], target, object1 [, objectN]);
// 将object 1~N 合并到target对象中
// 当deep设置为true时则深拷贝，未设置则为浅拷贝
// 属性值为undefined的属性会被舍弃

let data_3 = {};
$.extend(true, data_3, data_1);
console.log(data_3);
